package com.campus.lostandfound.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * AES 加密/解密工具类
 * 使用 AES-128 算法（密钥长度必须是 16 字节）
 */
public class AesUtil {

    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";

    /**
     * AES 加密
     *
     * @param plainText 明文
     * @param key       密钥（必须是 16 字节）
     * @return Base64 编码后的密文
     */
    public static String encrypt(String plainText, String key) {
        try {
            validateKey(key);
            
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            
            byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception e) {
            throw new RuntimeException("AES加密失败: " + e.getMessage(), e);
        }
    }

    /**
     * AES 解密
     *
     * @param encryptedText Base64 编码的密文
     * @param key           密钥（必须是 16 字节）
     * @return 明文
     */
    public static String decrypt(String encryptedText, String key) {
        try {
            validateKey(key);
            
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            
            byte[] decoded = Base64.getDecoder().decode(encryptedText);
            byte[] decrypted = cipher.doFinal(decoded);
            return new String(decrypted, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("AES解密失败: " + e.getMessage(), e);
        }
    }

    /**
     * 验证密钥长度
     *
     * @param key 密钥
     */
    private static void validateKey(String key) {
        if (key == null || key.isEmpty()) {
            throw new IllegalArgumentException("AES密钥不能为空");
        }
        
        int keyLength = key.getBytes(StandardCharsets.UTF_8).length;
        if (keyLength != 16) {
            throw new IllegalArgumentException(
                String.format("AES-128 密钥长度必须是 16 字节，当前长度: %d 字节", keyLength)
            );
        }
    }

    /**
     * 判断字符串是否为加密格式 ENC(...)
     *
     * @param value 待判断的字符串
     * @return true 如果是加密格式
     */
    public static boolean isEncrypted(String value) {
        return value != null && value.startsWith("ENC(") && value.endsWith(")");
    }

    /**
     * 从 ENC(...) 格式中提取密文
     *
     * @param encryptedValue ENC(...) 格式的字符串
     * @return 提取出的密文
     */
    public static String extractCiphertext(String encryptedValue) {
        if (!isEncrypted(encryptedValue)) {
            throw new IllegalArgumentException("不是有效的加密格式，必须是 ENC(...) 格式");
        }
        return encryptedValue.substring(4, encryptedValue.length() - 1);
    }

    /**
     * 将密文包装成 ENC(...) 格式
     *
     * @param ciphertext 密文
     * @return ENC(...) 格式的字符串
     */
    public static String wrapCiphertext(String ciphertext) {
        return "ENC(" + ciphertext + ")";
    }
}

